package dk.aiszone.lang.html.autosource;

import java.util.HashMap;
import java.util.Map;

import dk.aiszone.lang.autosource.generatorobjects.Annotation;
import dk.aiszone.lang.autosource.generatorobjects.Argument;
import dk.aiszone.lang.autosource.generatorobjects.Class;
import dk.aiszone.lang.autosource.generatorobjects.ClassBody;
import dk.aiszone.lang.autosource.generatorobjects.Declaration;
import dk.aiszone.lang.autosource.generatorobjects.JavaDoc;
import dk.aiszone.lang.autosource.generatorobjects.JavaFile;
import dk.aiszone.lang.autosource.generatorobjects.Method;
import dk.aiszone.lang.autosource.generatorobjects.Scope;
import dk.aiszone.lang.autosource.generatorobjects.Variable;

/**
 * Class used for generation an enum class.
 * 
 * @author Ais
 */
public class EnumClass extends JavaFile {

    private static final Map<String, String> ATTRIBUTES_CONVERSIONS = new HashMap<String, String>();
    static {
        ATTRIBUTES_CONVERSIONS.put("0", "ZERO");
        ATTRIBUTES_CONVERSIONS.put("1", "ONE");
    }

    private final ClassBody body;
    private final String enumName;

    /**
     * Constructor for the <code>EnumClass</code>.
     * 
     * @param _package
     *            The package of the class.
     * @param name
     *            The name of the enum class.
     */
    public EnumClass(String _package, String name) {
        this.enumName = capatialize(name);
        setPackageName(_package + ".enums");

        setBody(body = new ClassBody(new Declaration(Scope.PUBLIC, true, false, false), this.enumName));

        JavaDoc javadoc = new JavaDoc();
        javadoc.setDescription("Class containing the enum values of the HTML " + enumName + " value type");
        body.setJavaDoc(javadoc);

        Method toString = new Method(new Declaration(Scope.PUBLIC), new Class("String"), "toString");
        toString.appendToBody("return description;");
        toString.addAnnotation(new Annotation(new Class("Override")));
        body.addMethod(toString);

        Method constructor = new Method(new Declaration(Scope.PRIVATE), Class.CONSTRUCTOR, enumName);
        constructor.addArgument(new Argument(new Class("String"), "description"));
        constructor.appendToBody("this.description = description;");
        body.addMethod(constructor);

        Variable description = new Variable(new Declaration(Scope.PRIVATE), new Class("String"), "description");
        body.addVariable(description);
    }

    /**
     * Add a token value to the enum class.
     * 
     * @param value
     *            The token value to add.
     */
    public void addEnumValue(String value) {
        if (ATTRIBUTES_CONVERSIONS.containsKey(value)) {
            value = ATTRIBUTES_CONVERSIONS.get(value);
        }
        String upperValue = value.toUpperCase();

        Variable variable = new Variable(new Declaration(Scope.PUBLIC, true, true, false), new Class(enumName), upperValue);
        variable.setInitialization("new " + enumName + "(\"" + value + "\");");

        JavaDoc javadoc = new JavaDoc();
        javadoc.setDescription("Enum value representation of the " + upperValue + " token");
        variable.setJavaDoc(javadoc);

        body.addVariable(variable);
    }

    private String capatialize(String name) {
        return name.substring(0, 1).toUpperCase() + name.substring(1);
    }
}